<script setup lang="ts">
import type { Component } from "vue";

import type { AnyFunction } from "/@/vben/types";

import { computed, useTemplateRef, watch } from "vue";

import { useHoverToggle } from "/@/vben/hooks";
import { LockKeyhole, LogOut } from "/@/vben/icons";
import { $t } from "/@/vben/locales";
import { preferences, usePreferences } from "/@/vben/preferences";
import { useLockStore } from "/@/vben/stores";
import { isWindowsOs } from "/@/vben/utils";

import { useVbenModal } from "/@/vben//popup-ui";
import { Badge, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, VbenAvatar, VbenIcon } from "/@/vben//shadcn-ui";

import { useMagicKeys, whenever } from "@vueuse/core";

import { LockScreenModal } from "../lock-screen";

interface Props {
  /**
   * 头像
   */
  avatar?: string;
  /**
   * @zh_CN 描述
   */
  description?: string;
  /**
   * 是否启用快捷键
   */
  enableShortcutKey?: boolean;
  /**
   * 菜单数组
   */
  menus?: Array<{ handler: AnyFunction; icon?: Component; text: string }>;

  /**
   * 标签文本
   */
  tagText?: string;
  /**
   * 文本
   */
  text?: string;
  /** 触发方式 */
  trigger?: "both" | "click" | "hover";
  /** hover触发时，延迟响应的时间 */
  hoverDelay?: number;
}

defineOptions({
  name: "UserDropdown"
});

const props = withDefaults(defineProps<Props>(), {
  avatar: "",
  description: "",
  enableShortcutKey: true,
  menus: () => [],
  showShortcutKey: true,
  tagText: "",
  text: "",
  trigger: "click",
  hoverDelay: 500
});

const emit = defineEmits<{ logout: [] }>();

const { globalLockScreenShortcutKey, globalLogoutShortcutKey } = usePreferences();
const lockStore = useLockStore();
const [LockModal, lockModalApi] = useVbenModal({
  connectedComponent: LockScreenModal
});
const [LogoutModal, logoutModalApi] = useVbenModal({
  onConfirm() {
    handleSubmitLogout();
  }
});

const refTrigger = useTemplateRef("refTrigger");
const refContent = useTemplateRef("refContent");
const [openPopover, hoverWatcher] = useHoverToggle([refTrigger, refContent], () => props.hoverDelay);

watch(
  () => props.trigger === "hover" || props.trigger === "both",
  (val) => {
    if (val) {
      hoverWatcher.enable();
    } else {
      hoverWatcher.disable();
    }
  },
  {
    immediate: true
  }
);

const altView = computed(() => (isWindowsOs() ? "Alt" : "⌥"));

const enableLogoutShortcutKey = computed(() => {
  return props.enableShortcutKey && globalLogoutShortcutKey.value;
});

const enableLockScreenShortcutKey = computed(() => {
  return props.enableShortcutKey && globalLockScreenShortcutKey.value;
});

const enableShortcutKey = computed(() => {
  return props.enableShortcutKey && preferences.shortcutKeys.enable;
});

function handleOpenLock() {
  lockModalApi.open();
}

function handleSubmitLock(lockScreenPassword: string) {
  lockModalApi.close();
  lockStore.lockScreen(lockScreenPassword);
}

function handleLogout() {
  // emit
  logoutModalApi.open();
  openPopover.value = false;
}

function handleSubmitLogout() {
  emit("logout");
  logoutModalApi.close();
}

if (enableShortcutKey.value) {
  const keys = useMagicKeys();
  whenever(keys["Alt+KeyQ"]!, () => {
    if (enableLogoutShortcutKey.value) {
      handleLogout();
    }
  });

  whenever(keys["Alt+KeyL"]!, () => {
    if (enableLockScreenShortcutKey.value) {
      handleOpenLock();
    }
  });
}
</script>

<template>
  <LockModal v-if="preferences.widget.lockScreen" :avatar="avatar" :text="text" @submit="handleSubmitLock" />

  <LogoutModal
    :cancel-text="$t('common.cancel')"
    :confirm-text="$t('common.confirm')"
    :fullscreen-button="false"
    :title="$t('common.prompt')"
    centered
    content-class="px-8 min-h-10"
    footer-class="border-none mb-3 mr-3"
    header-class="border-none"
  >
    {{ $t("ui.widgets.logoutTip") }}
  </LogoutModal>

  <DropdownMenu v-model:open="openPopover">
    <DropdownMenuTrigger ref="refTrigger" :disabled="props.trigger === 'hover'">
      <div class="hover:bg-accent ml-1 mr-2 cursor-pointer rounded-full p-1.5">
        <div class="hover:text-accent-foreground flex-center">
          <VbenAvatar :alt="text" :src="avatar" class="size-8" dot />
        </div>
      </div>
    </DropdownMenuTrigger>
    <DropdownMenuContent class="mr-2 min-w-[240px] p-0 pb-1">
      <div ref="refContent">
        <DropdownMenuLabel class="flex items-center p-3">
          <VbenAvatar :alt="text" :src="avatar" class="size-12" dot dot-class="bottom-0 right-1 border-2 size-4 bg-green-500" />
          <div class="ml-2 w-full">
            <div v-if="tagText || text || $slots.tagText" class="text-foreground mb-1 flex items-center text-sm font-medium">
              {{ text }}
              <slot name="tagText">
                <Badge v-if="tagText" class="ml-2 text-green-400">
                  {{ tagText }}
                </Badge>
              </slot>
            </div>
            <div class="text-muted-foreground text-xs font-normal">
              {{ description }}
            </div>
          </div>
        </DropdownMenuLabel>
        <DropdownMenuSeparator v-if="menus?.length" />
        <DropdownMenuItem v-for="menu in menus" :key="menu.text" class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8" @click="menu.handler">
          <VbenIcon :icon="menu.icon" class="mr-2 size-4" />
          {{ menu.text }}
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem v-if="preferences.widget.lockScreen" class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8" @click="handleOpenLock">
          <LockKeyhole class="mr-2 size-4" />
          {{ $t("ui.widgets.lockScreen.title") }}
          <DropdownMenuShortcut v-if="enableLockScreenShortcutKey"> {{ altView }} L </DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuSeparator v-if="preferences.widget.lockScreen" />
        <DropdownMenuItem class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8" @click="handleLogout">
          <LogOut class="mr-2 size-4" />
          {{ $t("common.logout") }}
          <DropdownMenuShortcut v-if="enableLogoutShortcutKey"> {{ altView }} Q </DropdownMenuShortcut>
        </DropdownMenuItem>
      </div>
    </DropdownMenuContent>
  </DropdownMenu>
</template>
